package com.boe.csb.core.service.csb;

import com.alibaba.csb.console.sdk.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boe.csb.core.common.exception.CSBErrorCode;
import com.boe.csb.core.common.exception.CSBException;
import com.boe.csb.core.common.status.CertificationStatus;
import com.boe.csb.core.common.status.PublishStatusEnum;
import com.boe.csb.core.common.status.SubscribeStatusEnum;
import com.boe.csb.core.common.utils.CsbApiCaller;
import com.boe.csb.core.common.utils.MailTemplate;
import com.boe.csb.core.common.utils.MyRandomUtils;
import com.boe.csb.core.dao.BoeApiInfoCriteria;
import com.boe.csb.core.dao.BoeApiInfoMapper;
import com.boe.csb.core.dao.BoeUserMapper;
import com.boe.csb.core.entity.po.BoeUser;
import com.boe.csb.core.service.user.BoeUserService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Created by tianxiang.luo on 16/12/4.
 */

@Service("csbManagerOrderService")
public class CsbManagerOrderService {


    private final static String CREDENTIAL_NAME = "credential";
    //创建凭证
    private final static String CREATE_CREDENTIAL_API = "/api/credentials/create";
    //订购服务
    private final static String SUBSCRIBE_SERVICE = "/api/order/createOrUpdate";
    //检查凭证是否可以订购
    private final static String CHECK_ORDER_GROUP = "/api/order/checkOrderGroup";
    //查看订单
    private static final String ORDERS_FIND = "/api/orders/find";
    //批量删除订购
    private static final String DELETE_ORDERS = "/api/orders/delete";

    private static final List<String> API_CAN_READ = Arrays.asList(PublishStatusEnum.ACTIVE.getStatus(), PublishStatusEnum.STOP.getStatus());

    @Autowired
    private BoeUserService boeUserService;
    @Autowired
    private BoeUserMapper boeUserMapper;
    @Autowired
    private BoeApiInfoMapper boeApiInfoMapper;
    @Autowired
    private CsbAuditApiService csbAuditApiService;
    @Autowired
    private CsbAuditOrderService csbAuditOrderService;
    @Autowired
    private CsbManagerApiService csbManagerApiService;


    /**
     * 订购服务 (自动会创建凭证)
     */
    @Transactional
    public Result subscribeService(String userId, JSONObject jsonObject) {
        BoeUser boeUser = boeUserService.findBoeUser(userId);
        //判断是否有发布权限
        if (boeUser.getActiveStatus() == 0 || !CertificationStatus.ALLOW.getStatus().equals(boeUser.getAuditStatus())) {
            throw new CSBException(CSBErrorCode.USER_NOT_CERTIFICATION, "用户未认证");
        }
        String credentialGroupId = boeUser.getCredentialGroupId();
        String groupName = boeUser.getGroupName();
        //首先判断 凭证是否可用,可用就订购,不能用就去创建新的凭证
        Long serviceId = jsonObject.getLong("serviceId");
        //检查凭证是否可以用
        if (!checkOrderGroup(userId, String.valueOf(serviceId))) {
            //不可以用 重新创建
            Result result = createCredential(userId);
            if (result.isSuccess()) {
                JSONObject credentialGroup = result.getData().getJSONObject("credentialGroup");
                credentialGroupId = credentialGroup.getString("id");
                groupName = credentialGroup.getString("name");
                String sk = credentialGroup.getJSONObject("currentCredential").getString("secretKey");
                String ak = credentialGroup.getJSONObject("currentCredential").getString("accessKey");
                BoeUser updateUser = new BoeUser();
                updateUser.setId(Long.valueOf(userId));
                updateUser.setAk(ak);
                updateUser.setSk(sk);
                updateUser.setGroupName(groupName);
                updateUser.setCredentialId(Long.valueOf(credentialGroupId));
                boeUserMapper.updateByPrimaryKeySelective(updateUser);
            }
        }
        Map<String, String> map = new HashMap<>();
        map.put("userId", userId);
        map.put("csbId", CsbApiCaller.CSB_ID);
        JSONObject slaInfo = new JSONObject();
        if (jsonObject.get("qps") != null && jsonObject.get("qps") instanceof Integer) {
            slaInfo.put("qps", jsonObject.get("qps"));
        }
        if (jsonObject.get("qph") != null && jsonObject.get("qph") instanceof Integer) {
            slaInfo.put("qph", jsonObject.get("qph"));
        }
        jsonObject.put("credentialGroupId", credentialGroupId);
        jsonObject.put("groupName", groupName);
        jsonObject.put("csbId", CsbApiCaller.CSB_ID);
        jsonObject.put("slaInfo", slaInfo);
        
        csbManagerApiService.sendAdminUserMail(MailTemplate.SUBSCRIBE, serviceId.toString(),boeUser.getEmail()+"-"+boeUser.getId());
        
        // true 需要审批
        jsonObject.put("status", String.valueOf(SubscribeStatusEnum.INIT.getValue()));
        Result result = CsbApiCaller.callCsbPostApi(SUBSCRIBE_SERVICE, map, JSON.toJSONString(jsonObject));
        if (result.isSuccess()) {
            //如果不需要审核
            if (!csbAuditApiService.checkServiceIsAudit(serviceId)) {
                // 再调一次认证接口
                JSONObject info = result.getData().getJSONObject("info");
                Long orderId = info.getLong("id");
                JSONObject data = new JSONObject();
                JSONObject order = new JSONObject();
                order.put("orderId", orderId);
                order.put("status", "true");
                order.put("comment", "审批通过");
                data.put("order", order);
                data.put("serviceId", info.getLong("serviceId"));
                data.put("userId", Long.valueOf(info.getString("userId")));
                csbAuditOrderService.auditOrder(CsbApiCaller.CSB_ADMIN_ID, data);
            }
        }
        return result;
    }


    /**
     * 查看凭证是否可以订购
     */
    private boolean checkOrderGroup(String userId, String serviceId) {
        String credentialGroupId = boeUserService.findBoeUser(userId).getCredentialGroupId();
        if (credentialGroupId == null) return false;
        Map<String, String> map = new HashMap<>();
        map.put("userId", userId);
        map.put("serviceId", serviceId);
        map.put("csbId", CsbApiCaller.CSB_ID);
        map.put("credentialGroupId", credentialGroupId);
        Result result = CsbApiCaller.callCsbGetApi(CHECK_ORDER_GROUP, map);
        return result.isSuccess();
    }


    /**
     * 创建凭证
     */
    public Result createCredential(String userId) {
        String credentialName = CREDENTIAL_NAME + MyRandomUtils.randomUUID();
        JSONObject credential = new JSONObject();
        credential.put("name", credentialName);
        Map<String, String> map = new HashMap<>();
        map.put("userId", userId);
        map.put("csbId", CsbApiCaller.CSB_ID);
        Result result = CsbApiCaller.callCsbPostApi(CREATE_CREDENTIAL_API, map, JSON.toJSONString(credential));
        JSONObject credentialGroup = result.getData().getJSONObject("credentialGroup");
        String credentialGroupId = credentialGroup.getString("id");
        String credentialGroupName = credentialGroup.getString("name");
        Long credentialId = credentialGroup.getLong("id");
        String sk = credentialGroup.getJSONObject("currentCredential").getString("secretKey");
        String ak = credentialGroup.getJSONObject("currentCredential").getString("accessKey");
        if (result.isSuccess()) {
            BoeUser boeUser = new BoeUser();
            boeUser.setId(Long.valueOf(userId));
            boeUser.setCredentialGroupId(credentialGroupId);
            boeUser.setCredentialId(credentialId);
            boeUser.setGroupName(credentialGroupName);
            boeUser.setAk(ak);
            boeUser.setSk(sk);
            boeUserMapper.updateByPrimaryKeySelective(boeUser);
        }
        return result;
    }


    /**
     * 查看已经订阅的服务
     */
    public Result ownSubscribedService(String userId, Integer pageNum, Boolean showDelOrder, String serviceName, String alias, String status) {
        Map<String, String> queryMap = new HashMap<>();
        queryMap.put("userId", userId);
        queryMap.put("csbId", CsbApiCaller.CSB_ID);
        queryMap.put("pageNum", String.valueOf(pageNum));
        if (showDelOrder != null) {
            queryMap.put("showDelOrder", String.valueOf(showDelOrder));
        }
        if (serviceName != null) {
            queryMap.put("serviceName", serviceName);
        }
        if (alias != null) {
            queryMap.put("alias", alias);
        }
        if (status != null) {
            queryMap.put("status", status);
        }
        Result result = CsbApiCaller.callCsbGetApi(ORDERS_FIND, queryMap);
        JSONArray orderList = result.getData().getJSONArray("orderList");
        for (Object o : orderList) {
            Integer qps = 0;
            Integer qph = 0;
            JSONObject service = (JSONObject) o;
            JSONObject tmpSlaInfo = new JSONObject();
            JSONArray servOrderList = service.getJSONArray("orders");
            for (Object ord : servOrderList) {
                JSONObject jsonOrd = (JSONObject) ord;
                if (SubscribeStatusEnum.PASS.getValue().equals(jsonOrd.getInteger("status"))) {
                    tmpSlaInfo = jsonOrd.getJSONObject("slaInfo");
                    if (tmpSlaInfo == null) {
                        tmpSlaInfo = new JSONObject();
                    } else {
                        if (tmpSlaInfo.getInteger("qps") != null) {
                            qps = tmpSlaInfo.getInteger("qps");
                        }
                        if (tmpSlaInfo.getInteger("qph") != null) {
                            qph = tmpSlaInfo.getInteger("qph");
                        }
                    }
                    break;
                }
            }
            tmpSlaInfo.put("qps", qps);
            tmpSlaInfo.put("qph", qph);
            service.put("slaInfo", tmpSlaInfo);
        }
        return result;
    }

    /**
     * 退订服务
     */
    public Result deleteOrders(String userId, List<Long> serviceIdList) {
        Map<String, String> map = new HashMap<>();
        map.put("userId", userId);
        map.put("csbId", CsbApiCaller.CSB_ID);
        JSONObject data = new JSONObject();
        List<String> serviceStrIdList = new ArrayList<>();
        for (Long id : serviceIdList) {
            serviceStrIdList.add(String.valueOf(id));
        }
        data.put("serviceIdList", serviceStrIdList);
        return CsbApiCaller.callCsbPostApi(DELETE_ORDERS, map, JSONObject.toJSONString(data));
    }


    /**
     * 获取凭证
     */
    public Result findCredential(String userId) {
        String findCredentialApi = "/api/credentials/list";
        Map<String, String> map = new HashMap<>();
        map.put("userId", userId);
        map.put("csbId", CsbApiCaller.CSB_ID);
        map.put("pageNum", "1");
        return CsbApiCaller.callCsbGetApi(findCredentialApi, map);
    }

    // TODO: 17/1/3 最后一个订单是最新的还是第一个订单
    public Integer queryOrderStatus(String userId, Long serviceId, String serviceName) {
        if (userId == null || serviceId == null) {
            return SubscribeStatusEnum.NO_ORDER.getValue();
        } else {
            BoeApiInfoCriteria criteria = new BoeApiInfoCriteria();
            criteria.createCriteria().andCsbApiIdEqualTo(serviceId).andApiStatusNotIn(API_CAN_READ);
            long count = boeApiInfoMapper.countByExample(criteria);
            if (count > 0) {
                return SubscribeStatusEnum.CANNOT_SUBSCRIBE.getValue();
            }
            BoeUser boeUser = boeUserService.findBoeUser(userId);
            if (Boolean.TRUE.equals(boeUser.getIsAdmin())) {
                return SubscribeStatusEnum.NO_ORDER.getValue();
            }
            Map<String, String> map = new HashMap<>();
            map.put("csbId", CsbApiCaller.CSB_ID);
            map.put("userId", userId);
            map.put("serviceName", serviceName);
            map.put("serviceId",String.valueOf(serviceId));
            map.put("showDelOrder", "false");
            map.put("pageNum", "1");
            Result result = CsbApiCaller.callCsbGetApi(ORDERS_FIND, map);
            if (result.isSuccess()) {
                JSONObject reObj;
                //如果为空 没订阅  返回false
                JSONArray array = result.getData().getJSONArray("orderList");
                if (!CollectionUtils.isEmpty(array)) {

                    reObj = (JSONObject) array.get(0);
                    JSONArray orders = reObj.getJSONArray("orders");
                    JSONObject ord = (JSONObject) orders.get(0);
                    return ord.getInteger("status");
                }
            }
            return SubscribeStatusEnum.NO_ORDER.getValue();
        }
    }


}
